package com.retoc.oawx.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.retoc.oawx.common.util.R;
import com.retoc.oawx.config.shiro.JWTUtil;
import com.retoc.oawx.domain.req.*;
import com.retoc.oawx.exception.OAException;
import com.retoc.oawx.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Api("用户模块Web接口")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${oawx.jwt.cache-expire}")
    private int cacheExpire;

    @PostMapping("/register")
    @ApiOperation("注册用户")
    public R register(@Valid @RequestBody RegisterReq req){
        int id = userService.registerUser(req.getRegisterCode(), req.getCode(), req.getNickname(), req.getPhoto());
        String token = jwtUtil.createToken(id);
        Set<String> permsSet = userService.searchUserPermissions(id);
        saveCacheToken(token,id);
        return R.ok("注册成功").put("token",token).put("permission",permsSet);
    }

    @PostMapping("/login")
    @ApiOperation("登陆")
    public R login(@Valid @RequestBody LoginReq req, @RequestHeader("token") String token){
        Integer id;
        if (StrUtil.isNotEmpty(token)) {
            try{
                jwtUtil.verifierToken(token);   //验证令牌的有效性
            }catch (TokenExpiredException e){
                //如果令牌过期就生成新的令牌
                id = userService.login(req.getCode());
                token = jwtUtil.createToken(id);
                saveCacheToken(token, id);
            }
            id = jwtUtil.getUserId(token);
        } else {
            id = userService.login(req.getCode());
            token = jwtUtil.createToken(id);
            saveCacheToken(token, id);
        }
        Set<String> permsSet = userService.searchUserPermissions(id);
        return R.ok("登陆成功").put("token", token).put("permission", permsSet);
    }

    private void saveCacheToken(String token, int userId) {
        redisTemplate.opsForValue().set(token,userId+"",cacheExpire, TimeUnit.DAYS);
    }

    @GetMapping("/searchUserSummary")
    @ApiOperation("查询用户摘要信息")
    public R searchUserSummary(@RequestHeader("token") String token) {
        int userId = jwtUtil.getUserId(token);
        HashMap result = userService.searchUserDept(userId);
        result.put("userId", userId);
        return R.ok().put("result",result);
    }

    @PostMapping("/searchUserGroupByDept")
    @ApiOperation("查询员工部门信息")
    @RequiresPermissions(value = {"ROOT","EMPLOYEE:SELECT"},logical = Logical.OR)
    public R searchUserGroupByDept(@Valid @RequestBody SearchUserGroupbyDeptReq req){
        ArrayList<HashMap> hashMaps = userService.searchUserGroupByDept(req.getKeyword());
        return R.ok().put("result", hashMaps);
    }

    @PostMapping("/searchMembers")
    @ApiOperation("查询会议成员")
    @RequiresPermissions(value = {"ROOT","MEETING:INSERT","MEETING:UPDATE"},logical = Logical.OR)
    public R searchMembers(@Valid @RequestBody SearchMembersReq req){
        if (!JSONUtil.isJsonArray(req.getMembers())) {
            throw new OAException("不是JSON数组");
        }
        List<Integer> integers = JSONUtil.parseArray(req.getMembers()).toList(Integer.class);
        ArrayList<HashMap> result = userService.searchMembers(integers);
        return R.ok().put("result",result);
    }

    @PostMapping("/selectUserPhotoAndName")
    @ApiOperation("查询用户姓名和头像")
    @RequiresPermissions(value = {"WORKFLOW:APPROVAL"})
    public R selectUserPhotoAndName(@Valid @RequestBody UsersReq req){
        if (!JSONUtil.isJsonArray(req.getIds())){
            throw new OAException("参数不是JSON数组");
        }
        List<Integer> param = JSONUtil.parseArray(req.getIds()).toList(Integer.class);
        List<HashMap> list = userService.selectUserPhotoAndName(param);
        return R.ok().put("result",list);
    }

    @GetMapping("/searchUserContactList")
    @ApiOperation("查询通讯录列表")
    public R searchUserContactList() {
        JSONObject json = userService.searchUserContactList();
        return R.ok().put("result", json);
    }

    @GetMapping("/searchUserInfo")
    @ApiOperation("查询员工信息")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:SELECT"}, logical = Logical.OR)
    public R searchUserInfo(@RequestParam("userId") int userId){
        HashMap result = userService.searchUserInof(userId);
        return R.ok().put("result", result);
    }

    @GetMapping("/searchUserSelfInfo")
    @ApiOperation("查询用户信息")
    public R searchUserSelfInfo(@RequestHeader("token") String token) {
        int userId = jwtUtil.getUserId(token);
        HashMap map = userService.searchUserInof(userId);
        return R.ok().put("result", map);
    }

    @PostMapping("/updateUserInfo")
    @ApiOperation("更新用户数据")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:UPDATE"}, logical = Logical.OR)
    public R updateUserInfo(@Valid @RequestBody UpdateUserInfoReq req) {
        boolean root = false;
        if (!JSONUtil.isJsonArray(req.getRole())) {
            throw new OAException("role不是有效的JSON数组");
        } else {
            JSONArray role = JSONUtil.parseArray(req.getRole());
            root = role.contains(0) ? true : false;
        }
        HashMap param = new HashMap();
        param.put("name", req.getName());
        param.put("sex", req.getSex());
        param.put("deptName", req.getDeptName());
        param.put("tel", req.getTel());
        param.put("email", req.getEmail());
        param.put("hiredate", req.getHiredate());
        param.put("role", req.getRole());
        param.put("status", req.getStatus());
        param.put("userId", req.getUserId());
        param.put("root", root);

        int rows = userService.updateUserInfo(param);
        return R.ok().put("result", rows);
    }

    @PostMapping("/insertUser")
    @ApiOperation("添加员工数据")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:INSERT"}, logical = Logical.OR)
    public R insertUser(@RequestBody InsertUserReq req) {
        if (!JSONUtil.isJsonArray(req.getRole())) {
            throw new OAException("角色不是数组格式");
        }
        JSONArray array = JSONUtil.parseArray(req.getRole());
        HashMap param = new HashMap();
        param.put("name", req.getName());
        param.put("sex", req.getSex());
        param.put("tel", req.getTel());
        param.put("email", req.getEmail());
        param.put("hiredate", req.getHiredate());
        param.put("role", req.getRole());
        param.put("deptName", req.getDeptName());
        param.put("status", req.getStatus());
        param.put("createTime", new Date());
        if (array.contains(0)) {
            param.put("root", true);
        } else {
            param.put("root", false);
        }
        userService.insertUser(param);
        return R.ok().put("result", "success");
    }

    @PostMapping("/deleteUserById")
    @ApiOperation("删除员工记录")
    @RequiresPermissions(value = {"ROOT", "EMPLOYEE:DELETE"}, logical = Logical.OR)
    public R deleteUserById(@Valid @RequestBody DeleteUserReq req) {
        userService.deleteUserById(req.getId());
        return R.ok().put("result", "success");
    }

}
